﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MonsterEngine.Interfaces;

namespace MonsterEngine.Managers
{
    public class FightManager
    {
        private AbilityManager _abilityManager;
        private DamageManager _damageManager;

        public FightManager()
        {
        }

        public bool StartFight()
        {
            _damageManager = new DamageManager();
            _abilityManager = new AbilityManager();
            
            while (ContinueFight())
            {
                DoTurn();
                PlayerManager.SwitchPlayers();
            }
            return false;
        }

        private void DoTurn()
        {
            //
            PlayerManager.Player1.BuffList.ForEach(s => s.ExecuteAugment());
            if (PlayerManager.Player1.isActive)
            {
                GetTarget();

                GetCommandType();
            }
        }

        private void GetTarget()
        {
            Console.WriteLine("Target?");
            Console.WriteLine("1. " + PlayerManager.Player2.Name);
            Console.WriteLine("2. " + PlayerManager.Player1.Name);
            string targetId = Console.ReadLine();

            if (targetId == "1")
            {
                PlayerManager.Player1.Target = PlayerManager.Player2;
            }
            else
            {
                PlayerManager.Player1.Target = PlayerManager.Player1;
            }
        }

        private void GetCommandType()
        {
            Console.WriteLine("Command? ");
            // List out abilities and commands
            Console.WriteLine("1. Attack!");
            Console.WriteLine("2. Abilities!");
            Console.WriteLine("3. Defend!");
            Console.WriteLine("4. Give up!");

            int commandType = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine(String.Empty);

            switch (commandType)
            {
                case 1:
                    DoAttackCommand();
                    break;
                case 2:
                    DoAbilitiesCommand();
                    break;
                case 3:
                    DoDefendCommand();
                    break;
                case 4:
                    DoGiveUpCommand();
                    break;
                default:
                    break;
            }
        }

        private void DoGiveUpCommand()
        {
            throw new NotImplementedException();
        }

        private void DoDefendCommand()
        {
            throw new NotImplementedException();
        }

        private void DoAbilitiesCommand()
        {
            if (PlayerManager.Player1.AbilityList.Count() > 0)
            {
                Console.WriteLine("Ability List:");
                PlayerManager.Player1.AbilityList.ForEach(s =>
                    {
                        Console.WriteLine(s.AbilityKey + ": " + s.Name);
                    });
                Console.WriteLine("Enter key to use ability: ");

                string abilityNumber = Console.ReadLine();
                
                Console.WriteLine(String.Empty);

                if (String.IsNullOrEmpty(abilityNumber))
                {
                    GetCommandType();
                }
                else
                {
                    int abilityKey = int.Parse(abilityNumber);
                    IAbilities ability = PlayerManager.Player1.AbilityList.Where(s => s.AbilityKey == abilityKey).ToList()[0];
                    ability.AbilityTarget = PlayerManager.Player1.Target;
                    ExecuteAbility(ability);
                }
            }
            else
            {
                Console.WriteLine(PlayerManager.Player1.Name + " has no abilities!");
                GetCommandType();
            }
        }

        private void ExecuteAbility(IAbilities ability)
        {
            ability.AbilityDamageManager = _damageManager;
            _abilityManager.UseAbility(PlayerManager.Player1, PlayerManager.Player2, ability);
            ReportPlayers();
        }

        private void DoAttackCommand()
        {
            _damageManager.DamageCounter(_damageManager.DoRandomDamage(), Types.DamageType.Physical);
            ReportPlayers();
        }

        public void DetermineWhoGoesFirst()
        {
            Random rnd = new Random();
            int coin = rnd.Next(1, 3);

            Console.WriteLine("Coin was: " + coin);

            if (coin == 2)
            {
                // Sneak attack...
                PlayerManager.SwitchPlayers();
            }
        }

        private void ReportPlayers()
        {
            Console.WriteLine(String.Empty);
            Console.WriteLine(PlayerManager.Player1.Name + " sitting at " + PlayerManager.Player1.HitPoints);
            Console.WriteLine(PlayerManager.Player2.Name + " sitting at " + PlayerManager.Player2.HitPoints);
            Console.WriteLine(String.Empty);
        }

        public bool ContinueFight()
        {
            if (PlayerManager.Player1.HitPoints > 0 && PlayerManager.Player2.HitPoints > 0)
            {
                Console.WriteLine(PlayerManager.Player1.Name + "! Get Ready! ");
                return true;
            }

            ReportBattleResults();

            return false;
        }

        private void ReportBattleResults()
        {
            Console.WriteLine("Fight over, Winner: " + ((PlayerManager.Player1.HitPoints > 0) ? PlayerManager.Player1.Name : PlayerManager.Player2.Name));

            if (PlayerManager.Player1.HitPoints > 0)
            {
                LevelManager.DetermineLevelBonus(PlayerManager.Player1, PlayerManager.Player2);
            }
            else
            {
                LevelManager.DetermineLevelBonus(PlayerManager.Player2, PlayerManager.Player1);
            }
        }
    }
}
